package cn.com.wangluotongxin.linux.service.impl;

import cn.com.wangluotongxin.common.exceptions.BadResponseException;
import cn.com.wangluotongxin.linux.docker.LogContainerResultCallback;
import cn.com.wangluotongxin.linux.dto.DockerDto;
import cn.com.wangluotongxin.linux.service.IDockerService;
import cn.com.wangluotongxin.linux.vo.DockerLogVo;
import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.command.ListContainersCmd;
import com.github.dockerjava.api.command.LogContainerCmd;
import com.github.dockerjava.api.model.Container;
import com.github.dockerjava.core.DefaultDockerClientConfig;
import com.github.dockerjava.core.DockerClientBuilder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

@Slf4j
@Service
public class DockerServiceImpl implements IDockerService {

    private static DockerClient client = null;

    @Override
    public DockerLogVo getLogs(DockerDto dto) {
        String containerId = getDockerContainerIdByName(dto.getContainerName());
        log.info("docker container id: containerName={}, containerId={}", dto.getContainerName(), containerId);
        DockerLogVo vo = new DockerLogVo();
        try {
            LogContainerCmd logContainerCmd = getClient().logContainerCmd(containerId)
                    .withFollowStream(true)
                    .withStdErr(true)
                    .withStdOut(true)
                    .withTail(dto.getLine());

            String logs = logContainerCmd.exec(new LogContainerResultCallback()).toString((dto.getLine() <= 300? 1 : dto.getLine() / 300) * 0.5);
            logContainerCmd.close();
            vo.setLog(logs);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return vo;
    }

    public String getDockerContainerIdByName(String containerName) {
        try {
            ListContainersCmd listContainersCmd = getClient().listContainersCmd();
            listContainersCmd.withShowAll(true);
            Container container = listContainersCmd.exec().stream().filter(item->item.getNames()[0].equals("/" + containerName)).findFirst().orElse(null);
            if(container == null) {
                throw new BadResponseException("Docker容器不存在");
            }
            StringBuilder containerId = new StringBuilder();
            for(int i = 0; i < 12; i++) {
                containerId.append(container.getId().charAt(i));
            }
            return containerId.toString();
        } catch (Exception ex) {
            log.error("获取容器异常:containerName={}, error={}", containerName, ex.getMessage());
            throw new BadResponseException("获取Docker容器实例异常：" + ex.getMessage());
        }
    }

    private DockerClient getClient() {
        if(client != null) {
            return client;
        }
        client = DockerClientBuilder.getInstance(DefaultDockerClientConfig.createDefaultConfigBuilder().withDockerHost("unix:///root/var/run/docker.sock").build()).build();
        return client;
    }
}
